#ifndef TOOL_H_
#define TOOL_H_
#include "Types.h"


enum CorresType {CLOSEST, LANDMARK};

enum DataForm{MICCAI,HUAXI};

struct Paras
{   
    bool    initial;
    int     flow_filter;
    int     keyframe_inte;

    Scalar	alpha;              // 数据项权重
    Scalar	beta;               // level1 连接权重
    Scalar  gata;               // level2 连接权重
    Scalar  gamma;              // level3 连接权重
    Scalar  tps;                // tps损失


    int		max_iters;          // 求解器最大循环次数
    Scalar  stop;               // 优化器停止阈值
    Scalar  learning_rate;      // 学习率

    //数据相关参数
    DataForm    dataform;           // 什么数据格式 MICCAI or HUAXI
    int         max_picture_num;    // 融合的图片数量
    std::string datapath;           // 数据路径
    Eigen::Matrix3d K;
    int         n_strat_;           //以哪张图片开始

    Scalar searchratio;             //权重矩阵的搜索范围searchratio*redius
    Scalar Tps_R;
    Scalar DEM_resolusion;          //DEM地图的分辨率
    Scalar TPS_resolusion;          //tps控制点的采样分辨率

    Paras() // default
    {
        initial = true;    
        alpha = 1;      // data
        beta = 0.1;     // orth
        gata = 0.1;     // volume
        gamma = 0.1;    // smooth
        stop = 0.4;
        max_iters = 50;
        learning_rate = 0.001;

        dataform = HUAXI;
        // max_picture_num = 30;    //融合图片张数
        max_picture_num = 40;    //融合图片张数=200张数据集

        K <<394.55625300409247, 0.0, 163.9399642944336,
            0.0, 394.55625300409247,123.78474617004395, 
            0.0, 0.0, 1.0;

    }

};

void Pcshower(std::vector<PointCloud> Vpc,bool showxyzaxis,std::string windowsname);

PointCloud DownSample(double voxel_size,PointCloud pointcloud0);
PointCloud OutRemovel(int nb_points, double radius,PointCloud pointcloud0);
PointCloud OutRemovel(int nb_points, double radius,PointCloud pointcloud0,std::vector<size_t> &index);
MatrixXX Matirx_sq(MatrixXX M);

int Scalhash(int G,Eigen::Vector3i grid_coor);
int ghash(int G, Eigen::Vector3i grid_coor);

Eigen::Vector3i unhash(int value_hash,int G);
open3d::geometry::Image o3d_cv(const cv::Mat& A);
MatrixXX Matrix_inver(MatrixXX M);
void cor_line(std::vector<cv::Point> a,std::vector<cv::Point> b,cv::Mat img1, cv::Mat img2);
void saveMatrixToTxt(const Eigen::MatrixXd& matrix, const std::string& filename) ;
std::vector<size_t> FarthestPointDownSample(std::shared_ptr<open3d::geometry::PointCloud>& cloud,size_t sampleNum);


std::vector<Eigen::Vector3f> PC2float(PC pc);
#ifdef __linux__
bool my_mkdir(std::string file_path);
#endif

#endif